/*
 * Module name : CatalogComponent
 */
import Mn from 'backbone.marionette';
import Radio from 'backbone.radio';
import LoadingWidget from 'widgets/LoadingWidget.js';
import {
    getOpt,
} from "tools.js";
import CatalogTreeView from './CatalogTreeView.js';
import CatalogTreeCollection from '../models/CatalogTreeCollection.js';
import Validation from 'backbone-validation';
import {
    strToFloat,
} from "math.js";

const template = require('./templates/CatalogComponent.mustache');

/**
    Class displaying the sale_product catalog allowing item selection

    Expects the following options :

        collection_name

            The name of the collection in the associated Facade

        query_params

            The parameters used when querying the server to get the catalog items
        
        multiple 

            Default false : multiple selection allowed ?

    The Following options will be retrieved from the config Radio channel

        decimal_to_display

            Default 2 : How many decimals should we use to display numbers

        mode

            Default "ht": Computation mode

    Emits the following events :

        'catalog:insert' => ({sale_product_id: quantity})

            Emitted when the Insert button is clicked
            Pass the selected models : Object where key is id and the value is quantity

    */
const CatalogComponent = Mn.View.extend({
    className: 'modal_content_layout',
    template: template,
    regions: {
        main: '.main',
    },
    ui: {
        insert_btn: 'button[value=insert]',
        insert_for_edit_btn: 'button[value=insert_for_edit]',
        load_btn: 'button[value=load]',
        cancel_btn: 'button.reset',
        form: 'form'
    },
    // Listen to the current's view events
    events: {
        'click @ui.insert_btn': "onInsertClicked",
    },
    triggers: {
        'click @ui.cancel_btn': 'cancel:click'
    },
    initialize() {
        this.facade = Radio.channel('facade');
        // Params to use when querying the collections
        this.query_params = this.getOption('query_params');
        // Allow multiple selections ?
        this.multiple = getOpt(this, 'multiple', false);
        this.collection = new CatalogTreeCollection()
        this.collection.url = this.getOption('url');

        this.listenTo(this.facade, 'bind:validation', this.bindValidation);
        this.listenTo(this.facade, 'unbind:validation', this.unbindValidation);
        this.listenTo(this.model, 'validated:invalid', this.showErrors);
        this.listenTo(this.model, 'validated:valid', this.hideErrors.bind(this));
    },
    showErrors(model, errors) {
        this.$el.addClass('error');
    },
    hideErrors(model) {
        this.$el.removeClass('error');
    },
    bindValidation() {
        console.log("bindValidation");
        console.log(this.model);
        Validation.bind(this);
    },
    unbindValidation() {
        Validation.unbind(this);
    },
    showTree() {
        this.showChildView(
            'main',
            new CatalogTreeView({
                collection: this.collection,
                multiple: this.multiple,
            })
        );
        this.collection.on(
            'change:selected',
            this.onItemSelect,
            this
        );
        this.onItemSelect();
    },
    loadCatalogTree() {
        console.log(this.collection)
        const serverRequest = this.collection.fetch({
            data: this.getOption('query_params'),
            processData: true
        });
        serverRequest.done(
            () => this.showTree()
        );
    },
    onRender() {
        this.myid = _.uniqueId();
        console.log(this.myid);
        this.showChildView('main', new LoadingWidget());
        this.loadCatalogTree();
    },
    onItemSelect: function () {
        let models = this.collection.getSelected();
        let btn = this.getUI('insert_btn');
        let value = !(models.length > 0);
        btn.attr('disabled', value);
        btn.attr('aria-disabled', value);
    },
    onDomRemove() {
        this.collection.off('change:selected');
        this.collection.setNoneSelected();
    },
    onInsertClicked() {
        let models = this.collection.getSelected();

        // Cancel action if a model is not valid
        for (let idx in models) {
            let model = models[idx]
            if (!model.is_valid()) {
                return
            }
        }
        const result = models.reduce((dict, item) => {
            dict[item.get('id')] = strToFloat(item.get('quantity'));
            return dict;
        }, {});

        this.triggerMethod('catalog:insert', result);
    }
});
export default CatalogComponent;